#pragma once
#include <game/Config.h>
#include <game/Service.h>

#include <Config.h>
#include <WowPtr.h>
#include <boost/function.hpp>
#include <boost/bind.hpp>

ARELLO_GAME_NAMESPACE_DECL_START
namespace services {

template<typename T> void delayedDeleter(T* deleted) { delete deleted; }
template<typename T> void delayedWowDeleter(WowPtr<T> deleted) { delete static_cast<T*>(deleted); }

class DelayedActions
	: public Service<DelayedActions>
{
public:
	/** Given function will be executed right before frame rendering after all actors finish their life cycle.
	*
	*	This method is a perfect way to kill objects that are no longer needed but cannot be deleted immediately
	*	because of unfinished method calls on stack.
	*/
	virtual void Schedule(boost::function<void ()> action) = 0;

	/** Given function will be executed when specified amount of time passes. */
	virtual void ScheduleDeferred(time_float delay, boost::function<void ()> action) = 0;

	/** Helper to schedule deletion of an object of any type */
	template<typename T>
	void ScheduleDelete(T* deleted)
	{
		this->Schedule(boost::bind(&delayedDeleter<T>, deleted));
	}

	template <typename T>
	void ScheduleDelete(WowPtr<T> deleted)
	{
		this->Schedule(boost::bind(&delayedWowDeleter<T>, deleted));
	}
};

} // namespace services
ARELLO_GAME_NAMESPACE_DECL_END